HTML - Web Scrapping

O que é web Scrapping

Denominamos Web Scrapping a metodologia aplicada a obtenção de dados das páginas da Internet.

É muito útil para acompanhar os movimentos do(s) seu(s) concorrente(s) ou mesmo guiar a empresa no preço na composição do preço de um produto porque se um concorrente vende por um preço mais baixo o produto você terá dificuldades em concorrer com ele.

É preciso notar que qualquer informação publicada na Internet é pública mas não livre de direitos autorais. Portanto se eu pegar o valor de um produto de uma empresa e publicar em um site o produto e o preço dele eu preciso da permissão da empresa para fazer isso. Essa informação é de propriedade da empresa fabricante do produto.

Contudo há informações na Web que não são sigilosas e podemos coletar e publicar. Contudo o próprio Google coloca em primeiro a empresa originária da informação e a seguir as empresas que usam essas informações. A não ser que você pague para anunciar seu site.

Sites fontes de informação possuem 'mecanismos' para evitar o download das suas informações. Por exemplo, se você for na bolsa de Nova York e começar a trazer as empresas de tecnologia com maior lucratividade ( seria o foco para muitos investidores ) a partir da 500a página vai notar que o site começa a trazer dados de páginas que você já visitou, ou seja, ela para de enviar as novos dados e envia antigos tudo errado, de outras empresas. Você vai ter que aguardar o próximo dia para buscar mais e ai a atualização das informações do seu site fica comprometida. O correto é fazer uma assinatura da Bolsa de Nova York e conseguir a permissão dela para publicar essas informações o que faria o custo ser alto e provavelmente mal negócio e é assim que eles protegem o site deles.

Como é possível fazer o web Scrapping? Cadê a segurança ?

Para você publicar a informação na web você tem que deixar a informação exposta. A informação é pública mas tem direito autoral. Por exemplo, você entra num site querendo comprar um sapato. Você encontra o sapato que você quer mas não tem o preço, você tem que solicitar uma cotação de preço. Você faria negócio com esse site ? Se você está acostumado a comprar seus sapatos na Louis Vuitton, provavelmente, você deve estar acostumado a ir na loja pessoalmente para comprar mas fique sabendo que eles vendem pela Internet também. Se você está acostumado a comprar o sapato feito sob medida, feito a mão provavelmente aceitaria a indicação do site. Mas eu não, para mim o vendedor que quer vender o produto ou coloca o preço ou irá ficar com o produto, para mim é regra básica e ponto final, não perco tempo e vou para outro site. Pelo menos para mim, ou o cara expõe o valor do seu produto ou não vende..e aí se eu tenho acesso ao preço do produto, com certeza, um concorrente terá também acesso a essa informação...mas isso são regras de negócio como quem faz o preço é o mercado não a empresa fabricante do produto.

Como salvar a página Localmente

Se você está navegando aperte o botão F12 do seu navegador e selecione o item 'fontes' ou 'source'. Você verá o código na integra da página com as urls das imagens e tudo mais, até scripts. Lembro que tem direitos autorais nisso. Clique com o botão direito do mouse no item que deseja salvar e selecione 'Salvar Como'. Escolha uma pasta e salve o item. Você pode fazer isso com todos os componentes do site.

Primeiros Passos

No caso do 'web scrapping' você não perderá tempo fazendo o levantamento dos requisitos para a confecção do programa. Primeiro tenha certeza que a coisa funciona e depois bote a mão na massa.

A Etapa 1 é determinar a url de onde as informações que você precisa estão - Localize a página que estão as informações que deseja coletar.

No meu exemplo eu vou usar o google maps para obter a distância entre 2 pontos, origem e destino. A url básica é:
url = "https://www.google.com.br/maps/dir/"

Seguido dos dois endereços separados por /. No meu exemplo vou querer obter a distância entre o MASP na Av. Paulista (SP) e o Parque Ibirapuera. Veja como a url de exemplo ficaria depois de terminada :

https://www.google.com.br/maps/dir/Parque+Ibirapuera,+Av.+Pedro+%C3%81lvares+Cabral+-+Vila+Mariana,+S%C3%A3o+Paulo+-+SP,+04094-050/MASP+-+Museu+de+Arte+de+S%C3%A3o+Paulo+-+Avenida+Paulista+-+Bela+Vista,+S%C3%A3o+Paulo+-+SP/@-23.5754541,-46.6598563,15z/data=!3m1!4b1!4m13!4m12!1m5!1m1!1s0x94ce59f1069d11d1:0xcb936109af9ce541!2m2!1d-46.6576336!2d-23.5874162!1m5!1m1!1s0x94ce59ceb1eb771f:0xe904f6a669744da1!2m2!1d-46.6558831!2d-23.5614219

Se quiser testar montei a url acima num link...Clique aqui para abrir o Google Maps com os pontos informados acima.

Note que eu não coloquei as coordenadas geográficas dos pontos, só coloquei o endereço de origem e o de destino e o google maps fez isso. O Google Maps me deu o seguinte retorno:

Podemos ver que é exibido a distância e o tempo para ir de um local ao outro....19 minutos...4,5km. A distância não muda mas o tempo muda por causa do trânsito e por esse motivo escolhi só trabalhar com a distância.

Agora podemos exibir o código da página e procurar pela informação que nos interessa. Você tem que achar aonde a informação se encontra na página de uma forma segura, ou seja, com certeza ela está lá.

Caso tenha dificuldade em pegar o código da página, vá na página aberta do Google, Clique nos 3 pontos no topo superior direito da página, em seguinda selecione o item 'Mais ferramentas' e o item 'Salvar Página como...'...selecione uma pasta e um nome de arquivo para a página. Ela será salva no formato html mas pode abrir ela com um bloco de notas que vai funcionar.

Se precisar fazer uma pesquisa com ajuda do depurador faça o seguinte : no Browser, pressione F12, clique no ícone da setinha (item 1) para a esquerda no topo esquerdo da tela de debug e no mapa exibido na tela a esquerda ( item 2 ). Será exibido o código que gerou a imagem (item 3). Assim você tem um guia entre a página e o código.

Procurei a informação e no meu caso foi fácil..basta procurar por 'espaçokm' que acha de primeira....
São Paulo - SP\"]],[[[0,\"Alameda Campinas\",[4261,\"4,3 km\",0],[838,\"14 min\"],null,null

Localizada a informação podemos agora partir para o código.

Implementando o web Scrapping

Com tudo definido direitinho ficou fácil...

Página ASP

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Carrega Infos do Google Maps</title>
</head>
<body style="font-family:Calibri">
    <form id="form1" runat="server">
        <div>
            <h1>Exemplo Web Scrapping</h1>
            <p>
                <span style="display:inline-block;width:100px">Distancia : </span><asp:TextBox ID="txtDistancia" runat="server"></asp:TextBox>
            </p>

            <p>
                <span style="display:inline-block;width:100px">Msg : </span><asp:TextBox ID="txtmsg" runat="server" Width="500px"></asp:TextBox>
            </p>

            <p>
                <span style="display:inline-block;width:200px"> </span><asp:Button ID="btnProcessar" runat="server" Text="Processar" OnClick="btnProcessar_Click" />
            </p>

        </div>
    </form>
</body>
</html>

Código VB

Imports System.Net
Imports System.IO
Imports System.Threading

Public Class _Default
    Inherits System.Web.UI.Page

    Dim Erro As String = ""

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Public Function Limpa(dado As String) As String
        Dim a As String
        Dim b As Integer
        Dim c As Integer
        Dim d As Integer
        Dim e As Integer

        Try

            Erro = ""

            a = dado

            c = InStr(a, "\")
            d = InStrRev(a, "\")
            If c <> d Then
                e = InStr(a, " ")
                If e > c Then
                    'podando o inicio do str
                    a = Mid(a, InStr(a, "\") + 1)
                End If

            End If

            'podando o fim do str
            b = InStrRev(a, "\") - 1
            While b <> -1
                a = Left(a, b)
                b = InStrRev(a, "\") - 1
            End While

            While Not IsNumeric(Left(a, 1))
                a = Mid(a, 2)
            End While
            a = Left(a, InStr(a, " ") - 1)
            a = Replace(a, ",", ".")


            If Not IsNumeric(a) Then
                a = a
            End If
            Return a


        Catch ex As Exception
            Erro = ex.Message
            Return Nothing
        End Try
    End Function

    Protected Sub BtnProcessar_Click(sender As Object, e As EventArgs)
        Dim url As String
        Dim status As String
        Dim conteudo As String
        Dim c As String

        Try

            txtmsg.Text = ""
            txtmsg.BackColor = System.Drawing.Color.White

            url = "https://www.google.com.br/maps/dir/Parque+Ibirapuera,+Av.+Pedro+%C3%81lvares+Cabral+-+Vila+Mariana,+S%C3%A3o+Paulo+-+SP,+04094-050/MASP+-+Museu+de+Arte+de+S%C3%A3o+Paulo+-+Avenida+Paulista+-+Bela+Vista,+S%C3%A3o+Paulo+-+SP/@-23.5754541,-46.6598563,15z/data=!3m1!4b1!4m13!4m12!1m5!1m1!1s0x94ce59f1069d11d1:0xcb936109af9ce541!2m2!1d-46.6576336!2d-23.5874162!1m5!1m1!1s0x94ce59ceb1eb771f:0xe904f6a669744da1!2m2!1d-46.6558831!2d-23.5614219/"
            'Response.Redirect(url)

            Dim request As WebRequest = WebRequest.Create(url)
            request.Credentials = CredentialCache.DefaultCredentials
            Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
            status = response.StatusDescription

            If status = "OK" Then

                Dim dataStream As Stream = response.GetResponseStream()
                Dim reader As New StreamReader(dataStream)
                Dim responseFromServer As String = reader.ReadToEnd()
                conteudo = responseFromServer

                If InStr(conteudo, " km") > 0 Then

                    c = Mid(conteudo, InStr(conteudo, " km") - 5, 20)
                    c = Limpa(c)

                    If Erro <> "" Then
                        txtmsg.Text = "Erro na função Limpa1 : " + Erro
                        txtmsg.BackColor = System.Drawing.Color.Red
                        Exit Sub
                    End If

                    txtDistancia.Text = c

                Else
                    txtmsg.Text = "Erro acesso Google Maps: " + status
                End If
            End If

        Catch ex As Exception
            txtmsg.BackColor = System.Drawing.Color.Red
            txtmsg.Text = ex.Message
            Err.Clear()
        End Try

    End Sub
End Class

Finalizando

No exemplo acima eu mostrei como pegar um dado da web. Na minha aplicação ela consultava uma base de dados mysql, ia buscar a distância entre um ponto de partida ( onde a empresa se situa ) e a distância dos seus clientes. A aplicação voltava no servidor mysql e atualizava a distância do cliente.